package com.cne.gmail.Gmail.Handle;


import com.cne.gmail.Gmail.Excutor.AscWatchMailChange;
import com.cne.gmail.Gmail.Excutor.ThreadUpload;
import com.cne.gmail.Gmail.Util.CacheUtil;
import com.cne.gmail.Gmail.dao.AddressListRepository;
import com.cne.gmail.Gmail.model.AddressList;
import com.cne.gmail.Gmail.model.MessageModel;
import com.cne.gmail.Gmail.model.UserModel;
import com.cne.gmail.Gmail.service.BackendService;
import com.cne.gmail.Gmail.service.UserService;
import com.cne.gmail.Gmail.websocket.WsController;
import com.google.common.collect.Lists;
import lombok.extern.log4j.Log4j2;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.*;

@Log4j2
public class WatchHandler {
    public void handler(String emailAddress, UserService userService, BackendService backendService, WsController wsController, AddressListRepository repository
            , List<String> addresses) {
        UserModel user = userService.getUser(emailAddress);
        if (user!=null){
           try {
               AscWatchMailChange ascWatchMailChange=new AscWatchMailChange(user);
               Object o = CacheUtil.getCache().get(emailAddress+"_token");
               if (o==null){
                   Map map= ascWatchMailChange.call();
                   this.importMongo(map,user,backendService,wsController,repository,addresses);
               }
           }catch (Exception e){
               CacheUtil.CacheToken(user.getEmailAddress(),user.getAccessToken());
               log.info(emailAddress+"_token:"+user.getAccessToken());
               log.info(e.getMessage());
           }
        }
      }

      public void importMongo( Map<String, Set<String>>  map,UserModel user,BackendService backendService,WsController wsController,AddressListRepository repository,List<String> addresses) throws InterruptedException, ExecutionException {
          List<Callable<MessageModel>> tasks = new ArrayList<>();
              for (String id:map.keySet()){
                  for (String emailId:map.get(id)){
                      //判断当前的id数据库是否存在，如果存在就不重新插入，否则就插入到本地数据库
                       if (backendService.getMessage(emailId,user.getEmailAddress())==null){
                           Callable<MessageModel>  upload=   new ThreadUpload(id,user,emailId);
                           tasks.add(upload);
                       }
                  }
              }
          List<MessageModel> messageModels = new ArrayList<>();
          ExecutorService executorService = Executors.newFixedThreadPool(20);
          List<Future<MessageModel>> futures=executorService.invokeAll(tasks);
          for (Future<MessageModel> future:futures){
              messageModels.add(future.get());
          }
          executorService.shutdown();//关闭线程池
          if(messageModels.size()!=0&messageModels!=null){
             for (MessageModel messageModel:messageModels){
                 backendService.insertSingleInbox(messageModel);
             }
              for (MessageModel model:messageModels){
                  //判断当前的session中是否有用户，如果有就通知前端，如果没有则只保留到数据库中
                String result= model.getFrom();
                List<AddressList> addressLists= Lists.newArrayList();
                  if (addresses.size()!=0){
                      for (String address:addresses){
                          if (result.contains("<")&&result.contains(">")){
                              AddressList byMeAndAddress = repository.findByMeAndAddress(address, result.substring(result.indexOf("<") + 1, result.indexOf(">")));
                              addressLists.add(byMeAndAddress);
                          }else {
                              AddressList byMeAndAddress = repository.findByMeAndAddress(address, result);
                              addressLists.add(byMeAndAddress);
                          }
                      }
                  }
                  wsController.handleSubscribe(user.getEmailAddress(),addressLists,model);
              }
          }else {
              return;
          }
      }


}
